import {CreateElement, Vue} from "vue/types/vue";
import {VNode} from "vue";
import {DynamicForm} from "./index.vue.d";

export class DefaultForm {
  static span = 6
  static gutter = 20
  static labelAppend = "："
  static showTitle = false;
}

export type formItemsFunc = () => FormItemConfig[]

export class FormConfig {
  span = 6 // 全局宽度
  gutter = 20 // 距离
  inline = false // 行内
  labelPosition = 'top'
  labelWidth = '100px'
  events = {} // 记录事件
  showTitle = DefaultForm.showTitle // 表单是否显示title
  formItems: Array<FormItemConfig | formItemsFunc> = []

  constructor(self: FormConfig, formItems: Array<FormItemConfig | formItemsFunc>) {
    Object.keys(self).forEach(key => this[key] = self[key])
    this.formItems = formItems
  }
}

export class FormItemConfig {
  span = undefined // 宽度 默认为6
  label = undefined // 前面文字
  type = undefined // 类型---input
  prop = undefined // 字段
  props = undefined // 组件的props
  hidden = undefined // 组件隐藏false
  /**
   *
   * @param formData
   * @param formItem {FormItemConfig}
   */
  setHidden(formData, formItem) {
  } // 设置隐藏
  initValue = undefined // 初始化值
  setInitValue() {
    return ''
  }

  opacity = undefined // boolean 隐藏占位
  /**
   *
   * @param formData
   * @param formItem {FormItemConfig}
   */
  setOpacity(formData, formItem) {
  } //  隐藏元素，但是有占位
  getModel(value) { // model的单边实现
    return value
  }

  setModel(value) { // model的单边实现
    return value
  }

  /**
   * label自顶渲染函数, 同时支持使用作用域插槽，名字为 属性prop + ‘Label’
   * @param h
   * @param props
   * @param item {FormItemConfig}
   * @param labelAppend {string}
   * @return {VNode[]}
   */
  labelSlot(h, props, item, labelAppend) {
    return [h()]
  }

  /**
   * 初始化插槽数据
   * @param formData {{}}
   * @param item {FormItemConfig}
   */
  initSlotData(formData, item) {

  }

  /**
   * 全自定义渲染自己， 同时支持使用作用域插槽，名字为 属性prop
   * @param h
   * @param item {FormItemConfig}
   * @param formData {{}}
   * @return {VNode[]}
   */
  render(h, item, formData) {
    return [h()]
  }

  /**
   * 全自定义渲染自己， 同时支持使用作用域插槽，名字为 prop+'NoFormItem' 外部不渲染el-form-item
   * @param h
   * @param item {FormItemConfig}
   * @param formData {{}}
   * @return {VNode[]}
   */
  renderNoFormItem(h, item, formData) {
    return [h()]
  }

  events: ComEvents = undefined
  ref = undefined // 组件的引用
  /**
   * 组件插槽
   * @param h
   * @param item
   * @param formData 组件维护的表单对象
   * @return {TypeSlots}
   */
  typeSlots(h: CreateElement, item: FormItemConfig, formData): TypeSlots {
    return {} as TypeSlots
  }
}

export class TypeSlots {
  /**
   * 组件插槽渲染
   * @param props {?}
   * @return {VNode[]}
   */
  default(props): VNode[] {
    return []
  }

  [key: string]: (props) => VNode[]
}

export declare class ComEvents {
  /**
   *
   * @param val {number| string}
   */
  input: (val: number | string) => void
  /**
   *
   * @param val
   */
  change: (val) => void

  [key: string]: Function
}


export class RenderTypeItem {
  [comName: string]: Vue
}

export class GlobelConfig {
  /**
   * 外部组件
   */
  static externalComponents: RenderTypeItem = {}
}
